/**************************************************************
 * @file     Circular_buffer.c
 * @brief    提供创建环形缓冲区的接口和操作函数
 * @author   Ruilist
 * @date     2025-08-09
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *
 * @par 日志:
 * - V1.0.0 2025-08-09 Ruilist
 *   提供创建环形缓冲区的接口和操作函数
 **************************************************************/

//******************************** Includes *********************************//

#include "Circular_buffer.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

//******************************** Defines **********************************//

//******************************** Declaring ********************************//

Circular_buffer_status_t create_circular_buffer( circular_buffer_t **p_buffer )
{
    if ( NULL == p_buffer )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    *p_buffer = (circular_buffer_t *)malloc( sizeof( circular_buffer_t ) );
    if ( NULL == ( *p_buffer ) )
    {
        log_e( "create circular buffer faild-[%d]\r\n", NO_MEMORY_ERROR );
        return NO_MEMORY_ERROR;
    }
    memset( ( *p_buffer ), 0, sizeof( circular_buffer_t ) );
    // log_i( "create circular buffer successfully point is [%p]\r\n", ( *p_buffer ) );
    return CIRCULAR_BUFFER_OK;
}

Circular_buffer_status_t circular_buffer_status( circular_buffer_t *p_buffer )
{
    if ( NULL == p_buffer )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    if ( p_buffer->head == p_buffer->tail )
    {
        return BUFFER_IS_EMPTY;
    }
    else if ( ( ( ( p_buffer->head ) % CIRCULAR_BUFFER_SIZE ) ) ==
              ( ( p_buffer->tail ) % CIRCULAR_BUFFER_SIZE ) )
    {
        return BUFFER_IS_FULL;
    }
    else if ( p_buffer->head > p_buffer->tail )
    {
        return BUFFER_STORED;
    }
    return CIRCULAR_BUFFER_ERROR;
}

Circular_buffer_status_t insert_circular_buffer( circular_buffer_t *p_buffer, data_type_t data )
{
    if ( NULL == p_buffer )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    if ( BUFFER_IS_FULL == circular_buffer_status( p_buffer ) )
    {
        log_w( "insert circular error buffer is full-[%d]\r\n", BUFFER_IS_FULL );
        return BUFFER_IS_FULL;
    }
    p_buffer->data[( p_buffer->head ) % CIRCULAR_BUFFER_SIZE] = data;
    p_buffer->head++;
    return CIRCULAR_BUFFER_OK;
}

Circular_buffer_status_t read_circular_buffer( circular_buffer_t *p_buffer, data_type_t *p_data )
{
    if ( NULL == p_buffer || NULL == p_data )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    if ( BUFFER_IS_EMPTY == circular_buffer_status( p_buffer ) )
    {
        log_w( "read circular buffer faild-[%d]\r\n", BUFFER_IS_EMPTY );
        return BUFFER_IS_EMPTY;
    }
    *p_data = p_buffer->data[( p_buffer->tail ) % CIRCULAR_BUFFER_SIZE];
    p_buffer->tail++;
    return CIRCULAR_BUFFER_OK;
}

Circular_buffer_status_t get_head_circular_buffer( circular_buffer_t *p_buffer, uint32_t *p_head )
{
    if ( NULL == p_buffer || NULL == p_head )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    *p_head = p_buffer->head;
    return CIRCULAR_BUFFER_OK;
}

Circular_buffer_status_t head_offset_circular_buffer( circular_buffer_t *p_buffer, uint32_t offset )
{
    if ( NULL == p_buffer )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    for ( uint32_t i = 0; i < offset; i++ )
    {
        if ( BUFFER_IS_FULL == circular_buffer_status( p_buffer ) )
        {
            log_w( "p_buffer is FULL,head offset error \r\n" );
            return BUFFER_IS_FULL;
        }
        else
        {
            p_buffer->head++;
        }
    }
    return CIRCULAR_BUFFER_OK;
}

//******************************** Declaring ********************************//